package io.jpress.web.permission;

import com.jfinal.core.Action;
import com.jfinal.core.JFinal;
import io.jboot.utils.AnnotationUtil;
import io.jboot.utils.ClassScanner;
import io.jboot.utils.ClassUtil;
import io.jboot.utils.StrUtil;
import io.jpress.core.menu.MenuGroup;
import io.jpress.core.menu.MenuItem;
import io.jpress.core.menu.MenuManager;
import io.jpress.model.Permission;
import io.jpress.model.PermissionGroup;
import io.jpress.permission.*;
import io.jpress.permission.annotation.PermissionDef;

import java.util.*;

/**
 * @author michael yang (fuhai999@gmail.com)
 */
public class PermissionUtil {

    public static List<Permission> buildActionPermissions() {
        List<Permission> permissions = new ArrayList<>();

        List<String> allActionKeys = JFinal.me().getAllActionKeys();

        String[] urlPara = new String[1];

        for (String actionKey : allActionKeys) {

            Action action = JFinal.me().getAction(actionKey, urlPara);
            if (action == null) {
                continue;
            }

            PermissionDef annotation = action.getMethod().getAnnotation(PermissionDef.class);
            if (annotation == null) {
                continue;
            }

            Permission permission = new Permission();
            permission.setType(PermissionTypes.ACTION);
            permission.setId(actionKey);
            permission.setName(AnnotationUtil.get(annotation.title()));
            permission.setSortNo(annotation.sortNo());

            if (StrUtil.isNotBlank(AnnotationUtil.get(annotation.groupId()))) {
                permission.setGroupId(AnnotationUtil.get(annotation.groupId()));
            }

            permissions.add(permission);
        }

        return permissions;
    }


    public static List<Permission> buildMaintainerPermissions() {

        Set<Permission> permissions = new HashSet<>();

        List<Class<PermissionBuilder>> classes = ClassScanner.scanSubClass(PermissionBuilder.class, true);
        for (Class<PermissionBuilder> maintainerClass : classes) {
            PermissionBuilder maintainer = ClassUtil.newInstance(maintainerClass);
            if (maintainer == null) {
                continue;
            }
            List<PermissionBean> beans = maintainer.buildPermissions();
            if (beans != null) {
                for (PermissionBean bean : beans) {
                    Permission permission = new Permission();

                    permission.setId(bean.getId());
                    permission.setGroupId(bean.getGroupId());
                    permission.setName(bean.getName());
                    permission.setDescription(bean.getDescription());
                    permission.setType(bean.getType());
                    permission.setSortNo(bean.getSortNo());

                    permissions.add(permission);
                }
            }
        }


        return new ArrayList<>(permissions);
    }


    public static List<PermissionGroup> buildMaintainerPermissionGroups() {

        Set<PermissionGroup> groups = new HashSet<>();

        List<Class<PermissionGroupBuilder>> classes = ClassScanner.scanSubClass(PermissionGroupBuilder.class, true);
        for (Class<PermissionGroupBuilder> maintainerClass : classes) {
            PermissionGroupBuilder maintainer = ClassUtil.newInstance(maintainerClass);
            if (maintainer == null) {
                continue;
            }
            List<PermissionGroupBean> beans = maintainer.buildPermissionGroups();
            if (beans != null) {
                for (PermissionGroupBean bean : beans) {
                    PermissionGroup group = new PermissionGroup();
                    group.setId(bean.getId());
                    group.setName(bean.getName());
                    group.setDescription(bean.getDescription());
                    group.setType(bean.getType());
                    group.setSortNo(bean.getSortNo());

                    groups.add(group);
                }
            }
        }


        return new ArrayList<>(groups);
    }


    public static List<Permission> buildMenuPermissions() {
        Set<Permission> permissions = new HashSet<>();

        List<MenuGroup> allGroupMenus = getAllMenus();

        for (MenuGroup group : allGroupMenus) {

            List<MenuItem> childItems = group.getItems();
            if (childItems != null) {
                for (MenuItem childItem : childItems) {
                    Permission permission = new Permission();
                    permission.setType(PermissionTypes.MENU);
                    permission.setId(childItem.buildPermissionId());
                    permission.setGroupId(childItem.getGroupId());
                    permission.setSortNo(childItem.getOrder());
                    permission.setName(childItem.getText());
                    permissions.add(permission);
                }
            }
        }

        return new ArrayList<>(permissions);
    }


    public static List<PermissionGroup> buildMenuPermissionGroups() {
        Set<PermissionGroup> permissionGroups = new HashSet<>();

        List<MenuGroup> allGroupMenus = getAllMenus();

        for (MenuGroup menuGroup : allGroupMenus) {
            PermissionGroup permissionGroup = new PermissionGroup();
            permissionGroup.setType(PermissionTypes.MENU);
            permissionGroup.setId(menuGroup.getId());
            permissionGroup.setSortNo(menuGroup.getOrder());
            permissionGroup.setName(menuGroup.getText());

            permissionGroups.add(permissionGroup);
        }

        return new ArrayList<>(permissionGroups);
    }


    private static List<MenuGroup> getAllMenus() {
        List<MenuGroup> ret = new LinkedList<>();
        ret.addAll(MenuManager.me().getModuleMenus());
        ret.addAll(MenuManager.me().getSystemMenus());
        return ret;
    }
}
